#include "Nodo_ArbolTrie.h"
#include <iostream>
#include <list>
#include <sstream>
#include "stdio.h"
using namespace std;
#include "NodoHoja_ArbolTrie.h"
#include "OrdenadorLista.h"
#include "CompresorDelta.h"
#include "NodoLista.h"
#include "FreqDocumento.h"

Nodo_ArbolTrie::Nodo_ArbolTrie() {
}

bool Nodo_ArbolTrie::estaVacio(){
	return this->lista.empty();
}

void Nodo_ArbolTrie::setCaracter(char caracter) {
	Nodo_Lista nodo_aux(caracter);
	if(caracter == '/')
		nodo_aux.asignarTipoNodoHoja();
	else
		nodo_aux.asignarTipoNodoArbol();
	if(lista.back().getCaracter() < caracter)
		lista.push_back(nodo_aux);
	else {
		lista.push_back(nodo_aux);
		lista.sort(comparador);
	}
}

// Busqueda secuencial sobre la lista de nodo para la busqueda de caracter
bool Nodo_ArbolTrie::existe_caracter(char caracter) {
	//Nodo_Lista nodo_aux();

	if(!estaVacio()) {
		list<Nodo_Lista>::iterator it;
		for(it = lista.begin(); it != lista.end(); it++) {
			if((*it).getCaracter() == caracter)
				return true;
		}
	}
	return false;
}

void* Nodo_ArbolTrie::get_SigNodo(char caracter) {
	//Nodo_Lista nodo_aux();
	list<Nodo_Lista>::iterator it;
	for(it = lista.begin(); it != lista.end(); it++) {
		if((*it).getCaracter() == caracter)
			return (*it).get_NodoArbol();
	}
	return NULL;
}

void Nodo_ArbolTrie::vaciarNodo() {
	list<Nodo_Lista>::iterator it;
	char caracter;
	if(!lista.empty()) {
		for(it = lista.begin(); it != lista.end(); it++) {
			caracter = (*it).getCaracter();
			if(caracter != '/') {
				((Nodo_ArbolTrie*)(*it).get_NodoArbol())->vaciarNodo();
				//cout << caracter << endl;
				delete ((Nodo_ArbolTrie*)(it->get_NodoArbol()));
			}
			else {
				//cout << caracter << endl;
				//cout << "elimine el nodohoja 1" << endl;
				delete ((NodoHoja_ArbolTrie*)(it->get_NodoArbol()));
				//cout << "elimine el nodohoja 2" << endl;
			}
		}
	}
}

void Nodo_ArbolTrie::recorrer(std::fstream *terminos) {
	list<Nodo_Lista>::iterator it;
	list<FreqDocumento> *list_aux;
	list<FreqDocumento>::iterator it_hoja;
	static std::string termino;
	std::string aux;
	std::stringstream ss;
	// profundidad del árbol
	static int prof = 0;
	unsigned int num_doc = 0, frec = 0;
	CompresorDelta compresor;
	int i = 0;
	char caracter;
	if(!lista.empty()) {
		for(it = lista.begin(); it != lista.end(); it++) {
			caracter = (*it).getCaracter();
			if(caracter != '/') {
				termino += caracter;
				prof++;
				((Nodo_ArbolTrie*)(*it).get_NodoArbol())->recorrer(terminos);
				if(lista.size() == 1)
					termino.erase(termino.size() - 1);
				else {
					termino.erase(prof, 1);
				if(prof == 0)
					termino.erase(0, i + 1);
				}
			}
			else {
				//cout << "Termino a guardar: " << termino << endl;
				//getchar();
				list_aux = ((NodoHoja_ArbolTrie*)(it->get_NodoArbol()))->getFreqDocumento();
				*terminos << termino;
				aux = " ";
				for(it_hoja = list_aux->begin(); it_hoja != list_aux->end(); it_hoja++) {
					if((it_hoja->getNumDocumento() != NULL) && (it_hoja->getFrecuencia() != NULL)) {
						num_doc = compresor.descompresor(it_hoja->getNumDocumento());
						frec = compresor.descompresor(it_hoja->getFrecuencia());
						ss << num_doc;
						//cout << "NumDoc: "<< ss.str() << endl;
						//aux += " ";
						aux += ss.str();
						aux += " ";
						ss.str("");
						ss << frec;
						//cout << "Frec: "<< ss.str() << endl;
						aux += ss.str();
						aux += " ";
						ss.str("");
						//getchar();
					}
				}
				aux.erase(aux.size() - 1, 1);
				aux += '\n';
				*terminos << aux;
				if(lista.size() == 1)
					termino.erase(termino.size() - 1);
			}
			i++;
		}
	}
	prof--;
}

Nodo_ArbolTrie::~Nodo_ArbolTrie() {}
